`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:xzh 
// 
// Create Date: 2020/09/10 10:42:44
// Design Name: 
// Module Name: axi_to_sop_eop
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: axi\u8f6cll,\u652f\u6301\u8fde\u7eed\u7684axi_stream\u8f93\u5165,\u8f6c\u5316\u540e\u7684ll\u6570\u636e\u5e27\u95f4\u9694\u81f3\u5c11\u4e3a1clk,\u6a21\u5757\u6ca1\u6709\u7f13\u5b58\u529f\u80fd\u548cready\u6807\u5fd7
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
`include "top_define.v"
module axi_to_sop_eop(
    //clock & reset
    input   wire                  pkt_clk             ,
    input   wire                  pkt_rst_n           ,
    input   wire    [9:0]           ram_2p_cfg_register,
    //axi_stream in
    input   wire    [ 255:   0]   in_axis_rdata       ,
    input   wire                  in_axis_rvalid      ,
    input   wire                  in_axis_rlast       ,
    input   wire    [  31:   0]   in_axis_rkeep       ,
    //pkt out
    output  reg     [ 255:   0]   pkt_rx_data         ,
    output  reg                   pkt_rx_eop          ,
    output  reg     [   4:   0]   pkt_rx_mod          ,
    output  reg                   pkt_rx_sop          ,
    output  reg                   pkt_rx_dval         ,
    //discard
    input   wire                  i_discard
);
 

(*mark_debug = "true"*) reg  [255:0] axis_rdata   ;
(*mark_debug = "true"*) reg          axis_rvalid  ;
(*mark_debug = "true"*) reg          axis_rlast   ;
(*mark_debug = "true"*) reg  [31:0]  axis_rkeep   ;
(*mark_debug = "true"*) reg          axis_rstart  ;
//
(*mark_debug = "true"*) reg discard_state ;

//fifo
(*mark_debug = "true"*) reg  [289:0] fifo_data_i ;
(*mark_debug = "true"*) wire [289:0] fifo_data_o ;
(*mark_debug = "true"*) reg  fifo_we ;
(*mark_debug = "true"*) wire fifo_full ;
(*mark_debug = "true"*) wire fifo_empty ;
(*mark_debug = "true"*) reg fifo_rd_temp ;
(*mark_debug = "true"*) wire fifo_rd ;
(*mark_debug = "true"*) reg fifo_rd_dl1 ;


//---------------------------------------------
//axi
//---------------------------------------------
//axis_rdata
always @(posedge pkt_clk ) begin
    if (in_axis_rvalid==1'b1) begin
        axis_rdata  <= { in_axis_rdata[ 7: 0], in_axis_rdata[15: 8], in_axis_rdata[23:16], in_axis_rdata[31:24], in_axis_rdata[39:32], in_axis_rdata[47:40], in_axis_rdata[55:48], in_axis_rdata[63:56],
                        in_axis_rdata[71:64], in_axis_rdata[79:72], in_axis_rdata[87:80], in_axis_rdata[95:88], in_axis_rdata[103:96], in_axis_rdata[111:104], in_axis_rdata[119:112], in_axis_rdata[127:120],
                        in_axis_rdata[135:128], in_axis_rdata[143:136], in_axis_rdata[151:144], in_axis_rdata[159:152], in_axis_rdata[167:160], in_axis_rdata[175:168], in_axis_rdata[183:176], in_axis_rdata[191:184],
                        in_axis_rdata[199:192], in_axis_rdata[207:200], in_axis_rdata[215:208], in_axis_rdata[223:216], in_axis_rdata[231:224], in_axis_rdata[239:232], in_axis_rdata[247:240], in_axis_rdata[255:248]
                         }  ;
    end
    else begin
        axis_rdata <= 256'b0 ;
    end
end

//axis_rvalid
always @(posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n==1'b0) begin
        axis_rvalid <= 1'b0 ;
    end
    else begin
        axis_rvalid <= in_axis_rvalid ;
    end
end

//axis_rlast
always @(posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n==1'b0) begin
        axis_rlast <= 1'b0 ;
    end
    else if (in_axis_rvalid==1'b1&&in_axis_rlast==1'b1) begin
        axis_rlast <= 1'b1 ;
    end
    else begin
        axis_rlast <= 1'b0 ;
    end
end


//
reg flag ; 
//flag
always @(posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n==1'b0) begin
        flag <= 1'b0 ;
    end 
    else if ( in_axis_rvalid==1'b1&&in_axis_rlast==1'b1 ) begin
        flag <= 1'b0 ;
    end
    else if ( ( in_axis_rvalid == 1'b1 && axis_rvalid == 1'b0 ) || ( in_axis_rvalid == 1'b1 && axis_rlast == 1'b1 ) ) begin //|in_axis_rvalid\u4e2d\u65ad||in_axis_rvalid\u975e\u4e2d\u65ad|
        flag <= 1'b1 ;
    end
    else begin
        flag <= flag ;
    end
end 


//\u652f\u6301\u4e2d\u65ad\u3001\u8fde\u7eeddval
//axis_rstart
always @(posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n==1'b0) begin
        axis_rstart <= 1'b0 ;
    end 
    else if ( flag == 1'b0 && ( ( in_axis_rvalid == 1'b1 && axis_rvalid == 1'b0 ) || ( in_axis_rvalid == 1'b1 && axis_rlast == 1'b1 ) ) ) begin //|in_axis_rvalid\u4e2d\u65ad||in_axis_rvalid\u975e\u4e2d\u65ad|
        axis_rstart <= 1'b1 ;
    end
    else begin
        axis_rstart <= 1'b0 ;
    end
end



//axis_rkeep
always @(posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n==1'b0) begin     
        axis_rkeep <= 32'b0 ;
    end 
    else begin
        axis_rkeep  <= { in_axis_rkeep[0], in_axis_rkeep[1], in_axis_rkeep[2], in_axis_rkeep[3], in_axis_rkeep[4], in_axis_rkeep[5], in_axis_rkeep[6], in_axis_rkeep[7],
                         in_axis_rkeep[8], in_axis_rkeep[9], in_axis_rkeep[10], in_axis_rkeep[11], in_axis_rkeep[12], in_axis_rkeep[13], in_axis_rkeep[14], in_axis_rkeep[15],
                         in_axis_rkeep[16], in_axis_rkeep[17], in_axis_rkeep[18], in_axis_rkeep[19], in_axis_rkeep[20], in_axis_rkeep[21], in_axis_rkeep[22], in_axis_rkeep[23],
                         in_axis_rkeep[24], in_axis_rkeep[25], in_axis_rkeep[26], in_axis_rkeep[27], in_axis_rkeep[28], in_axis_rkeep[29], in_axis_rkeep[30], in_axis_rkeep[31]
                     } ;
    end
end 
//---------------------------------------------
//---------------------------------------------


//---------------------------------------------
//fifo \u5199
//---------------------------------------------
//\u5199\u6570\u636e                    
always @(posedge pkt_clk ) begin
    if ( axis_rvalid == 1'b1 )
        fifo_data_i <= { axis_rstart , axis_rlast ,axis_rkeep ,axis_rdata } ; //1 1 32 256
    else begin
        fifo_data_i <= 290'b0 ;
    end
end

//\u5199\u4f7f\u80fd
always @(posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n == 1'b0) 
        fifo_we <= 1'b0 ;
    else if ( axis_rvalid == 1'b1 && fifo_full == 1'b0 ) //\u7406\u8bba\u4e0a\u4e0d\u4f1a\u51fa\u73b0fifo_full,\u56e0\u4e3aFIFO\u4e24\u8fb9\u662f\u76f8\u540c\u7684\u65f6\u949f\u8bfb\u5199,\u5982\u679c\u51fa\u73b0full\u5c31\u662f\u9519\u8bef
        fifo_we <= 1'b1 ; 
    else 
        fifo_we <= 1'b0 ;
end


//---------------------------------------------
//fifo \u8bfb
//---------------------------------------------
//discard state
always @( posedge pkt_clk or negedge pkt_rst_n ) begin
    if (pkt_rst_n==1'b0) begin
        discard_state <= 1'b0 ;
    end
    else if ( fifo_rd == 1'b1 && fifo_rd_dl1 == 1'b0 && i_discard == 1'b1 ) begin
        discard_state <= 1'b1 ;
    end
    else if ( fifo_rd == 1'b0 && fifo_rd_dl1 == 1'b1 ) begin
        discard_state <= 1'b0 ;
    end
    else begin
        discard_state <= discard_state ; 
    end
end

//\u8bfb\u4f7f\u80fd,\u8bfb\u5b8c\u4e00\u4e2aemac\u5e27\u540e\u81f3\u5c11\u505c\u6b62\u4e00\u4e2a\u65f6\u949f
always @(posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n == 1'b0) 
        fifo_rd_temp <= 1'b0 ;
    else if ( fifo_empty == 1'b0 )
        fifo_rd_temp <= 1'b1; 
    else 
        fifo_rd_temp <= 1'b0 ;
end

assign fifo_rd = fifo_rd_temp & ( ! ( fifo_data_o[288] & fifo_rd_dl1 ) )  ;

//fifo_rd_dl1
always @(posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n==1'b0) begin
        fifo_rd_dl1 <= 1'b0 ;
    end
    else begin
        fifo_rd_dl1 <= fifo_rd ;
    end
end

//pkt_rx_sop
always @( posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n == 1'b0) 
        pkt_rx_sop <= 1'b0 ;
    else if ( fifo_rd_dl1 == 1'b1 && discard_state == 1'b0)
        pkt_rx_sop <= fifo_data_o[289];
    else 
        pkt_rx_sop <= 1'b0 ;
end



//pkt_rx_eop
always @( posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n == 1'b0) 
        pkt_rx_eop <= 1'b0 ;
    else if ( fifo_rd_dl1 == 1'b1 && discard_state == 1'b0)
        pkt_rx_eop <= fifo_data_o[288] ;
    else 
        pkt_rx_eop <= 1'b0 ;
end

//pkt_rx_data
always @( posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n == 1'b0) 
        pkt_rx_data <= 256'b0 ;
    else if ( fifo_rd_dl1 == 1'b1 && discard_state == 1'b0)
        pkt_rx_data <= fifo_data_o[255:0];
    else 
        pkt_rx_data <= 256'b0 ;
end

//pkt_rx_dval
always @( posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n == 1'b0) 
        pkt_rx_dval <= 1'b0 ;
    else if(discard_state == 1'b0)
        pkt_rx_dval <= fifo_rd_dl1 ;
    else pkt_rx_dval <= 1'b0;
end

//pkt_rx_mod
always @( posedge pkt_clk or negedge pkt_rst_n) begin
    if (pkt_rst_n == 1'b0) 
        pkt_rx_mod <= 5'b0 ;  
    else if ( fifo_rd_dl1 == 1'b1 && fifo_data_o[288] == 1'b1 && discard_state == 1'b0 )
         case ( fifo_data_o[287:256] )
            32'b1111_1111_1111_1111_1111_1111_1111_1111 : pkt_rx_mod <= 5'd0 ;
            32'b1111_1111_1111_1111_1111_1111_1111_1110 : pkt_rx_mod <= 5'd31;
            32'b1111_1111_1111_1111_1111_1111_1111_1100 : pkt_rx_mod <= 5'd30;
            32'b1111_1111_1111_1111_1111_1111_1111_1000 : pkt_rx_mod <= 5'd29;
            32'b1111_1111_1111_1111_1111_1111_1111_0000 : pkt_rx_mod <= 5'd28;
            32'b1111_1111_1111_1111_1111_1111_1110_0000 : pkt_rx_mod <= 5'd27;
            32'b1111_1111_1111_1111_1111_1111_1100_0000 : pkt_rx_mod <= 5'd26;
            32'b1111_1111_1111_1111_1111_1111_1000_0000 : pkt_rx_mod <= 5'd25 ;
            32'b1111_1111_1111_1111_1111_1111_0000_0000 : pkt_rx_mod <= 5'd24 ;
            32'b1111_1111_1111_1111_1111_1110_0000_0000 : pkt_rx_mod <= 5'd23 ;
            32'b1111_1111_1111_1111_1111_1100_0000_0000 : pkt_rx_mod <= 5'd22 ;
            32'b1111_1111_1111_1111_1111_1000_0000_0000 : pkt_rx_mod <= 5'd21 ;
            32'b1111_1111_1111_1111_1111_0000_0000_0000 : pkt_rx_mod <= 5'd20 ;
            32'b1111_1111_1111_1111_1110_0000_0000_0000 : pkt_rx_mod <= 5'd19 ;
            32'b1111_1111_1111_1111_1100_0000_0000_0000 : pkt_rx_mod <= 5'd18 ;
            32'b1111_1111_1111_1111_1000_0000_0000_0000 : pkt_rx_mod <= 5'd17 ;
            
            32'b1111_1111_1111_1111_0000_0000_0000_0000 : pkt_rx_mod <= 5'd16 ;
            32'b1111_1111_1111_1110_0000_0000_0000_0000 : pkt_rx_mod <= 5'd15;
            32'b1111_1111_1111_1100_0000_0000_0000_0000 : pkt_rx_mod <= 5'd14;
            32'b1111_1111_1111_1000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd13;
            32'b1111_1111_1111_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd12;
            32'b1111_1111_1110_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd11;
            32'b1111_1111_1100_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd10;
            32'b1111_1111_1000_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd9 ;
            32'b1111_1111_0000_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd8 ;
            32'b1111_1110_0000_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd7 ;
            32'b1111_1100_0000_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd6 ;
            32'b1111_1000_0000_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd5 ;
            32'b1111_0000_0000_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd4 ;
            32'b1110_0000_0000_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd3 ;
            32'b1100_0000_0000_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd2 ;
            32'b1000_0000_0000_0000_0000_0000_0000_0000 : pkt_rx_mod <= 5'd1 ;
            default : pkt_rx_mod <= 5'd0 ;
        endcase  
    else 
        pkt_rx_mod <= 5'b0 ;
end
`ifdef ASIC
axi_2_pkt_fifo U_axi_2_pkt_fifo(
	.clk(pkt_clk),
	.clr(pkt_rst_n),
    .ram_2p_cfg_register(ram_2p_cfg_register),
	.w_data(fifo_data_i),
	.w_we(fifo_we),
	.w_full(),
	.w_afull(fifo_full),
	.r_data(fifo_data_o),
	.r_re(fifo_rd),
	.r_empty(fifo_empty),
	.r_aempty()
	);
`else
axi_2_pkt_asyn_fifo U_axi_2_pkt_asyn_fifo (
  .rst(~pkt_rst_n),
  .clk(pkt_clk),            // input wire wr_clk
  .din(fifo_data_i),                  // input wire [351 : 0] din
  .wr_en(fifo_we),              // input wire wr_en
  .rd_en(fifo_rd),              // input wire rd_en
  .dout(fifo_data_o),                // output wire [351 : 0] dout
  .full(fifo_full ),                // output wire full
  .empty(fifo_empty)              // output wire empty
);
`endif

endmodule 
